package utils

import (
	"context"
	"football/src/log"
	"math/rand"
	"mime/multipart"
	"strings"

	"github.com/minio/minio-go/v7"
	"github.com/minio/minio-go/v7/pkg/credentials"
	"github.com/spf13/viper"
	"go.uber.org/zap"
	"gorm.io/gorm"
)

func GenerateRandomString(length int) string {
	const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
	var sb strings.Builder
	for i := 0; i < length; i++ {
		sb.WriteByte(charset[rand.Intn(len(charset))])
	}
	return sb.String()
}

func Error(msg string, err error) {
	log.Error(msg, zap.String("error", err.Error()))
}

// UploadToMinio 上传文件到 MinIO
func UploadToMinio(objectName string, file *multipart.FileHeader) error {
	// 初始化 MinIO 客户端
	endpoint := viper.GetString("minio.ip")
	accessKeyID := viper.GetString("minio.accessKey")
	secretAccessKey := viper.GetString("minio.secretKey")
	bucket := viper.GetString("minio.bucket")
	useSSL := false // 根据需要设置为 true 或 false

	minioClient, err := minio.New(endpoint, &minio.Options{
		Creds:  credentials.NewStaticV4(accessKeyID, secretAccessKey, ""),
		Secure: useSSL,
	})
	if err != nil {
		Error("连接 MinIO 失败", err)
		return err
	}

	// 检测连接
	if _, err := minioClient.ListBuckets(context.Background()); err != nil {
		Error("与 MinIO 的连接检验失败", err)
		return err
	} else {
		log.Info("成功连接到 MinIO")
	}

	// 打开上传的文件
	src, err := file.Open()
	if err != nil {
		Error("打开文件时出错:", err)
		return err
	}
	defer src.Close()

	// 上传到 MinIO
	if _, err := minioClient.PutObject(context.Background(), bucket, objectName, src, file.Size, minio.PutObjectOptions{}); err != nil {
		Error("上传文件时出错:", err)
		return err
	}

	log.Info("成功上传:")
	return nil
}

func Paginate[T any](query *gorm.DB, page int, limit int) ([]*T, int, error) {
	var items []*T
	var total int64

	// 计算总记录数
	if err := query.Count(&total).Error; err != nil {
		return nil, 0, err
	}

	// 获取分页结果
	if err := query.Limit(limit).Offset((page - 1) * limit).Find(&items).Error; err != nil {
		return nil, 0, err
	}

	return items, int(total), nil
}
